import * as THREE from '../../build/three.module.js';
import {
  OrbitControls
} from '../../jsm/controls/OrbitControls.js';

let scene = new THREE.Scene();

/**
 * 通过自定义几何体来展示点、线、面与3D模型间的关系
 */
let geo = new THREE.BufferGeometry(); // 一个基于缓冲区的模型几何体对象

// 构建顶点数组
/**
 * BufferGeometry 只能接受由类型数组构成的顶点坐标集合来创建几何模型
 * 因此，需要通过js的类型数组来定义顶点坐标
 */
let vertexs = new Float32Array([
  0, 0, 0, // 第一个顶点坐标
  0, 100, 0, // 第二个顶点坐标
  100, 0, 0, // 第三个顶点坐标

  0, 0, 25, // 第四个顶点
  0, 0, 150, // 第五个顶点
  100, 0, 25, // 第六个顶点
]);

// 创建属性缓冲区对象
let attribute = new THREE.BufferAttribute(vertexs, 3);
// 这里的 3 表示：每三个项构成一个顶点的xyz坐标值。
// 而每三个顶点构成一个三角面
// 设置几何体对象的位置属性
geo.attributes.position = attribute;

// 构建材质对象，渲染三角面
let matBasic = new THREE.MeshBasicMaterial({
  color: 0x0000ff,
  side: THREE.DoubleSide // 两面可见，因为现在的网格模型只是一个面
});
let meshBasic = new THREE.Mesh(geo, matBasic); // 无论多么复杂几何模型，本质都是一系列的顶点构成的几何体(geometry) 加上 各种材质类型(material) 组成
// 基础材质以面为单位进行渲染
scene.add(meshBasic);

// 点模型
let matPoint = new THREE.PointsMaterial({
  color: 0xff0000,
  size: 10, // 绘制的小正方形大小
});
let points = new THREE.Points(geo, matPoint);
scene.add(points);

// 线模型
let matLine = new THREE.LineBasicMaterial({
  color: 0x00ff00
});
let lines = new THREE.Line(geo, matLine);
scene.add(lines);

// 相机
let width = window.innerWidth,
    height = window.innerHeight,
    k = width / height,
    s = 200,
    camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
camera.position.set(400, 400, 400);
camera.lookAt(scene.position);

// 渲染器
let renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
renderer.setClearColor(0xaaaaaa);
document.body.appendChild(renderer.domElement);

// 坐标辅助线
// let axesH = new THREE.AxesHelper(200);
// scene.add(axesH);

function render () {
  requestAnimationFrame(render);
  renderer.render(scene, camera);
}
render();

new OrbitControls(camera, renderer.domElement);